package com.jdd.modules.people.controller;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jdd.common.api.vo.Result;
import com.jdd.common.system.vo.LoginUser;
import com.jdd.common.util.LoginUserUtils;
import com.jdd.common.util.ResultGenerator;
import com.jdd.common.util.excel.entity.params.ExportParams;
import com.jdd.common.util.excel.web.entity.vo.NormalExcelConstants;
import com.jdd.common.util.excel.web.view.EasypoiSingleExcelView;
import com.jdd.dao.entity.*;
import com.jdd.dao.service.*;
import com.jdd.modules.device.entity.TDevice;
import com.jdd.modules.device.service.TDeviceService;
import com.jdd.modules.people.dto.DeleteEntity;
import com.jdd.modules.people.entity.Bind;
import com.jdd.modules.people.model.AreaIdModel;
import com.jdd.modules.people.model.TAreaTreeModel;
import com.jdd.modules.people.model.TProjectTreeModel;
import com.jdd.modules.people.util.FindAreaChildrenUtil;
import com.jdd.modules.people.vo.AreaSearchVo;
import com.jdd.modules.people.vo.AreaVo;
import com.jdd.modules.people.vo.GetAreaListReqVo;
import com.jdd.utils.SnowFlakeUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author zly
 * @since 2022-01-21
 */
@Slf4j
@Api("区域")
@RestController("TAreaController")
@RequestMapping("/area")
public class TAreaController {
	@Resource
    private TAreaService tAreaService;
    @Resource
    private TProjectService tProjectService;

    @Resource
    private ITBuildingService tBuildingService;

    @Resource
    private TDeviceService tTDeviceService;

    @Resource
    private ITUnitService tUnitService;

    @Resource
    private ITFloorService floorService;

    @Resource
    private ITHouseService houseService;

    @Resource
    private TDeviceService deviceService;
    @PostMapping("/add")
    public Result add(@RequestBody TArea tArea, HttpServletRequest req) {
        /*为空说明是新增*/
        if (StringUtils.isEmpty(tArea.getId())) {
            tArea.setId(SnowFlakeUtil.getId());
        }else{
            /*说明是修改，判断是否有重复区域,重命名需要更改设备别名（所处位置）*/
            QueryWrapper<TArea> tAreaQueryWrapper   = new QueryWrapper<>();
            tAreaQueryWrapper.eq("name",tArea.getName());
            TArea area = tAreaService.getById(tArea.getId());
            tAreaQueryWrapper.eq("parent_id",area.getParentId());
            int count = tAreaService.count(tAreaQueryWrapper);
            if (count>0){
                return ResultGenerator.genFailResult("该区域下已经存在此区域");
            }
            /*先判断区域下是否存在设备*/
            String deviceParentCode = area.getParentCode() + "A" + area.getCode();
            /*有设备时在执行此操作，更换设备的别名*/
            tTDeviceService.updateDeviceAlias(deviceParentCode,1, area.getParentCode(),tArea.getName());
        }
        tAreaService.saveOrUpdate(tArea);
        return ResultGenerator.genSuccessResult(tArea);
    }

    @GetMapping("/check")
    public Result check(TArea tArea){
        QueryWrapper<TArea> tAreaQueryWrapper   = new QueryWrapper<>();
        tAreaQueryWrapper.eq("parent_id",tArea.getParentId());
        tAreaQueryWrapper.eq("name",tArea.getName());
        int count = tAreaService.count(tAreaQueryWrapper);
        if (count>0){
            return ResultGenerator.genFailResult("该区域下已经存在此区域");
        }

        return ResultGenerator.genSuccessResult();
    }


    @PostMapping("/bind")
    public Result bind(@RequestBody Bind bind) {
        log.info("bind:{}", bind);
        String id = SnowFlakeUtil.getId();
        TArea area = new TArea();
        area.setId(id);
        area.setParentId(bind.getParentId());
        area.setName(bind.getAreaName());
        String parentCode="";
        String sysProjectCode="";
        String projectId="";
        if (bind.getParentType().equals(0)) {
            TProject parentProject = tProjectService.getById(area.getParentId());
//             lastOrgCode = tAreaService.getLastCreateAreaOrgCode(parentProject.getSysProjectCode());
//            parentOrgCode = parentProject.getOrgCode();
            parentCode = "D"+parentProject.getCode();
            sysProjectCode = parentProject.getSysProjectCode();
            projectId = parentProject.getId();
        } else {
            TArea parentArea = tAreaService.getById(area.getParentId());
            parentCode = parentArea.getParentCode()+"A"+parentArea.getCode();
            sysProjectCode = parentArea.getSysProjectCode();
            projectId = parentArea.getProjectId();
        }
        area.setParentCode(parentCode);
        area.setSysProjectCode(sysProjectCode);
        area.setProjectId(projectId);
        tAreaService.save(area);
        return ResultGenerator.genSuccessResult("绑定成功");
    }

    @PostMapping("/deleteById/{id}")
    public Result deleteById(@PathVariable String id) {
        tAreaService.removeById(id);
        return ResultGenerator.genSuccessResult(id);
    }

    @ApiOperation(value = "通过id删除", notes = "通过id删除")
    @DeleteMapping(value = "/delete")
    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
        try {
            int count = tBuildingService.count(new QueryWrapper<TBuilding>().eq("area_id", id));
            if (count > 0) {
                return ResultGenerator.genFailResult("该区域已绑定楼栋");
            }
            int count2 = tAreaService.count(new QueryWrapper<TArea>().eq("parent_id", id));
            if (count2 > 0) {
                return ResultGenerator.genFailResult("所选区域拥有子区域，请先删除子区域");
            }
            int count3 = tTDeviceService.count(new QueryWrapper<TDevice>().eq("area_id",id));
            if (count3 > 0) {
                return ResultGenerator.genFailResult("所选区域拥有设备，请先删除设备");
            }
            //删除区域
            tAreaService.removeById(id);
        } catch (Exception e) {
            log.info("删除区域发生异常:{}",e);
            return ResultGenerator.genFailResult("删除失败");
        }
        return ResultGenerator.genSuccessResult("删除成功");
    }

    /*传入id，返回该id下的子节点*/
    @GetMapping("/getChildren")
    public Result<List<TProjectTreeModel>> getChildren(@RequestParam(name = "id")String id){
        List<TProjectTreeModel> tProjectTreeModels = new ArrayList<>();
        LambdaQueryWrapper<TArea> tAreaLambdaQueryWrapper = new LambdaQueryWrapper<>();
        tAreaLambdaQueryWrapper.eq(TArea::getParentId,id);
        List<TArea> areaList = tAreaService.list(tAreaLambdaQueryWrapper);
        for (TArea tArea : areaList) {
            tProjectTreeModels.add(new TProjectTreeModel(tArea));
        }
        LambdaQueryWrapper<TBuilding> tBuildingLambdaQueryWrapper =new LambdaQueryWrapper<>();
        tBuildingLambdaQueryWrapper.eq(TBuilding::getAreaId,id);
        List<TBuilding> tBuildingList = tBuildingService.list(tBuildingLambdaQueryWrapper);
        for (TBuilding tBuilding : tBuildingList) {
            tProjectTreeModels.add(new TProjectTreeModel(tBuilding));
        }
        return ResultGenerator.genSuccessResult(tProjectTreeModels);
    }
    /*传入id，返回该id下的子节点*/
    @GetMapping("/getChildrenWithDevice")
    public Result<List<TProjectTreeModel>> getChildrenWithTDevice(@RequestParam(name = "id")String id){
        List<TProjectTreeModel> tProjectTreeModels = new ArrayList<>();
        LambdaQueryWrapper<TArea> tAreaLambdaQueryWrapper = new LambdaQueryWrapper<>();
        tAreaLambdaQueryWrapper.eq(TArea::getParentId,id);
        List<TArea> areaList = tAreaService.list(tAreaLambdaQueryWrapper);
        TArea area = tAreaService.getById(id);
        LambdaQueryWrapper<TDevice> deviceLambdaQueryWrapper = new LambdaQueryWrapper<>();
        deviceLambdaQueryWrapper.eq(TDevice::getAreaId, id);
        deviceLambdaQueryWrapper.isNull(TDevice::getBuildingId).or().eq(TDevice::getBuildingId,"");
        List<TDevice> deviceList = deviceService.list(deviceLambdaQueryWrapper);
        for (TDevice device : deviceList) {
            tProjectTreeModels.add(new TProjectTreeModel(device,area));
        }

        for (TArea tArea : areaList) {
            tProjectTreeModels.add(new TProjectTreeModel(tArea));
        }
        LambdaQueryWrapper<TBuilding> tBuildingLambdaQueryWrapper =new LambdaQueryWrapper<>();
        tBuildingLambdaQueryWrapper.eq(TBuilding::getAreaId,id);
        List<TBuilding> tBuildingList = tBuildingService.list(tBuildingLambdaQueryWrapper);
        for (TBuilding tBuilding : tBuildingList) {
            tProjectTreeModels.add(new TProjectTreeModel(tBuilding));

        }
        return ResultGenerator.genSuccessResult(tProjectTreeModels);
    }


    /*判断每个节点是否含有设备的方法*/
    public boolean judgeTDevice(int isArea,String key){
        QueryWrapper<TDevice> wrapper = new QueryWrapper<>();
        String columnName="";
        if (isArea==1){
            columnName = "area_id";
        }else if (isArea==2){
            columnName = "building_id";
        }else if (isArea==3){
            columnName = "unit_id";
        }else if (isArea==4){
            columnName = "floor_id";
        }
        wrapper.eq(columnName,key);
        TDevice tTDevice = tTDeviceService.getOne(wrapper);
        if (tTDevice!=null){
            return false;
        }
        return true;
    }

    /*删除树状结构中的数据*/
    @PostMapping(value = "/deleteBatch")
    public Result<?> deleteBatch(@RequestBody List<DeleteEntity> DeleteEntitys) {

        for (DeleteEntity deleteEntity : DeleteEntitys) {
            QueryWrapper<TDevice> wrapper = new QueryWrapper<>();
            if (deleteEntity.getIsArea()==1){
                wrapper.eq("area_id",deleteEntity.getId());
                List<TDevice> list = tTDeviceService.list(wrapper);
                if (list.size()>0){
                    return ResultGenerator.genFailResult(deleteEntity.getTitle()+"下绑定了设备，请删除完设备后再删除此项");
                }
//                if (judgeTDevice(tProjectTreeModel.getIsArea(),tProjectTreeModel.getKey())){
//                    return ResultGenerator.genFailResult(tProjectTreeModel.getName()+"下绑定了设备，请删除完设备后再删除此项");
//                }
                tAreaService.removeById(deleteEntity.getId());
            }else if (deleteEntity.getIsArea()==2){
                wrapper.eq("building_id",deleteEntity.getId());
                List<TDevice> list = tTDeviceService.list(wrapper);
                if (list.size()>0){
                    return ResultGenerator.genFailResult(deleteEntity.getTitle()+"绑定了设备，请删除完设备后再删除此项");
                }
                tBuildingService.removeById(deleteEntity.getId());
            }else if (deleteEntity.getIsArea()==3){
                wrapper.eq("unit_id",deleteEntity.getId());
                List<TDevice> list = tTDeviceService.list(wrapper);
                if (list.size()>0){
                    return ResultGenerator.genFailResult(deleteEntity.getTitle()+"绑定了设备，请删除完设备后再删除此项");
                }
                tUnitService.removeById(deleteEntity.getId());
            }else if (deleteEntity.getIsArea()==4){
                wrapper.eq("floor_id",deleteEntity.getId());
                List<TDevice> list = tTDeviceService.list(wrapper);
                if (list.size()>0){
                    return ResultGenerator.genFailResult(deleteEntity.getTitle()+"绑定了设备，请删除完设备后再删除此项");
                }

                floorService.removeById(deleteEntity.getId());
            }else if (deleteEntity.getIsArea()==5){
                wrapper.eq("house_id",deleteEntity.getId());
                List<TDevice> list = tTDeviceService.list(wrapper);
                if (list.size()>0){
                    return ResultGenerator.genFailResult(deleteEntity.getTitle()+"绑定了设备，请删除完设备后再删除此项");
                }
                houseService.removeById(deleteEntity.getId());
            }
        }
        return ResultGenerator.genSuccessResult("删除成功");

//        if (keys.size() == 0) {
//            return ResultGenerator.genFailResult("参数有误");
//        }
//        List<String> areaIds = new ArrayList<>();
//        List<String> projectIds = new ArrayList<>();
//        for (String key : keys) {
//            TArea area = tAreaService.getById(key);
//            if (area != null) {
//                areaIds.add(area.getId());
//            } else {
//                TProject tProject = tProjectService.getById(key);
//                if (tProject != null) {
//                    projectIds.add(tProject.getId());
//                } else {
//                    return ResultGenerator.genFailResult("参数有误");
//                }
//            }
//        }
//        if (projectIds.size() != 0) {
//            int count = tAreaService.count(new QueryWrapper<TArea>().in("parent_id", projectIds));
//            if (count > 0) {
//                return ResultGenerator.genFailResult("所选项目拥有区域未删除，请先删除区域");
//            }
//        }
//        try {
//            if (areaIds.size() > 0) {
//                tAreaService.removeByIds(areaIds);
//            }
//            if (projectIds.size() > 0) {
//                tProjectService.removeByIds(projectIds);
//            }
//        } catch (Exception e) {
//            return ResultGenerator.genFailResult("删除失败");
//        }
//        return ResultGenerator.genSuccessResult("删除成功");
    }





    @PostMapping("/updateById")
    public Result updateById(@RequestBody TArea tArea) {
        if (tArea.getId() == null) {
            return ResultGenerator.genFailResult("id为空，修改失败");
        }
        tAreaService.updateById(tArea);
        return ResultGenerator.genSuccessResult(tArea);
    }

    @GetMapping("/selectById/{id}")
    public Result selectById(@PathVariable String id) {
        TArea tArea = tAreaService.getById(id);
        return ResultGenerator.genSuccessResult(tArea);
    }

    @GetMapping("/getAreaList")
    public Result<List<TArea>> getAreaList(@RequestParam("projectId") String projectId) {
        List<TArea> list = new ArrayList<>();
        getChildrenList(projectId, list);
        Result<List<TArea>> result = new Result<>();
        result.setResult(list);
        result.setSuccess(true);
        return result;
    }

    private void getChildrenList(String parentId, List<TArea> list) {
        LambdaQueryWrapper<TArea> wrapper = new LambdaQueryWrapper();
        wrapper.eq(TArea::getParentId, parentId);
        List<TArea> areaList = tAreaService.list(wrapper);
        if (areaList != null) {
            list.addAll(areaList);
            for (TArea tArea : areaList) {
                getChildrenList(tArea.getId(), list);
            }
        }
    }

    @PostMapping("/getAreaList")
    public Result getAreaList(@RequestBody @Valid GetAreaListReqVo reqVo) {
        Page<TArea> pageTemp = new Page<TArea>(reqVo.getPageNo(), reqVo.getPageSize());
        QueryWrapper<TArea> wrapper = getWrapper(reqVo);
        IPage<TArea> page = tAreaService.page(pageTemp, wrapper);
        return ResultGenerator.genSuccessResult(page);
    }

    @GetMapping("/areaVoList")
    public Result<IPage<AreaVo>> areaVoList(AreaSearchVo areaSearchVo, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        Result<IPage<AreaVo>> result = new Result<IPage<AreaVo>>();
        LoginUser loginUser = LoginUserUtils.getLoginUser();
        if(CollUtil.isEmpty(loginUser.getProjectCodes()))
        {
            result.setSuccess(true);
            return result;
        }
        Page<AreaVo> page = new Page<AreaVo>(pageNo, pageSize);
        IPage<AreaVo> pageList = tAreaService.getAreaInfoPage(page, areaSearchVo,loginUser.getProjectCodes());
        result.setSuccess(true);
        result.setResult(pageList);
        return result;
    }

    @PostMapping("/cancleBind")
    public Result cancleBind(@RequestBody AreaVo areaVo) {
        if (areaVo.getParentId() == null || areaVo.getParentId() == "") {
            return ResultGenerator.genFailResult("解绑失败,该项目没有设定区域");
        }
        List<TProject> projects = tProjectService.selectByAreaId(areaVo.getParentId());
        if (projects.size() < 0) {
            tAreaService.removeById(areaVo.getId());
        }
        LambdaUpdateWrapper<TProject> wrapper = new LambdaUpdateWrapper<TProject>();
        wrapper.eq(TProject::getId, areaVo.getId());
        wrapper.set(TProject::getSysAreaId, null);
        boolean update = tProjectService.update(wrapper);
        if (update) {
            return ResultGenerator.genSuccessResult("取消绑定成功");
        } else {
            return ResultGenerator.genFailResult("绑定失败");
        }
    }

    @RequestMapping(value = "/searchBy", method = RequestMethod.GET)
    public Result<List<TAreaTreeModel>> searchBy(@RequestParam(name = "keyWord", required = true) String keyWord) {
        Result<List<TAreaTreeModel>> result = new Result<List<TAreaTreeModel>>();
        try {
            List<TAreaTreeModel> treeList = this.tAreaService.searhBy(keyWord);
            if (treeList.size() == 0 || treeList == null) {
                throw new Exception();
            }
            result.setSuccess(true);
            result.setResult(treeList);
            return result;
        } catch (Exception e) {
            e.fillInStackTrace();
            result.setSuccess(false);
            result.setMessage("查询失败或没有您想要的任何数据!");
            return result;
        }


    }

    @GetMapping("/getAreaListAll")
    public Result getAreaListAll() {
        QueryWrapper<TArea> wrapper = new QueryWrapper<>();
        wrapper.eq("status", 1);
        wrapper.orderByDesc("create_time");
        List<TArea> list = tAreaService.list(wrapper);
        return ResultGenerator.genSuccessResult(list);
    }

    /**
     * 查询数据 查出所有部门,并以树结构数据格式响应给前端
     *
     * @return
     */
    @RequestMapping(value = "/queryTreeList", method = RequestMethod.GET)
    public Result<List<TAreaTreeModel>> queryTreeList() {
        Result<List<TAreaTreeModel>> result = new Result<>();
        try {
            List<TAreaTreeModel> list = tAreaService.queryTreeList();
            result.setResult(list);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return result;
    }

    /**
     * 查询数据 添加或编辑页面对该方法发起请求,以树结构形式加载所有部门的名称,方便用户的操作
     *
     * @return
     */
    @RequestMapping(value = "/queryIdTree", method = RequestMethod.GET)
    public Result<List<AreaIdModel>> queryIdTree() {
        Result<List<AreaIdModel>> result = new Result<List<AreaIdModel>>();
        List<AreaIdModel> idList;
        try {
            idList = FindAreaChildrenUtil.wrapAreaIdModel();
            if (idList != null && idList.size() > 0) {
                result.setResult(idList);
                result.setSuccess(true);
            } else {
                tAreaService.queryTreeList();
                idList = FindAreaChildrenUtil.wrapAreaIdModel();
                result.setResult(idList);
                result.setSuccess(true);
            }
            return result;
        } catch (Exception e) {
            log.error(e.getMessage(),e);
            result.setSuccess(false);
            return result;
        }
    }


    /**
     * 导出excel
     *
     * @param request
     * @param response
     */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response, GetAreaListReqVo reqVo) {
        QueryWrapper<TArea> wrapper = getWrapper(reqVo);
        ModelAndView mv = new ModelAndView(new EasypoiSingleExcelView());
        List<TArea> pageList = tAreaService.list(wrapper);
        //导出文件名称
        mv.addObject(NormalExcelConstants.FILE_NAME, "区域列表");
        mv.addObject(NormalExcelConstants.CLASS, TArea.class);
        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("区域列表数据", "导出信息"));
        mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
        return mv;
    }

    public QueryWrapper<TArea> getWrapper(GetAreaListReqVo reqVo) {
        QueryWrapper<TArea> wrapper = new QueryWrapper<>();
        if (StringUtils.isEmpty(reqVo.getName())) {
            wrapper.like("name", reqVo.getName());
        }
        wrapper.orderByAsc("status").orderByDesc("create_time");
        return wrapper;
    }
}
